#include "libacl.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void usage() {
    printf("Uso: acl_set <archivo> <uid> <permisos>\n");
    printf("  <archivo> es el archivo cuya ACL se modifica\n");
    printf("  <uid> es el ID de usuario a modificar\n");
    printf("  <permisos> son los bits de permisos en formato rwxrwx\n");
}


int existeUID(short uid) {
    FILE* usrdb;
    char* usrname;
    char line[256];
    short usr = 0;
    
    usrdb = fopen(PASSWD_FILE, "r");
    if (usrdb != NULL) {
        while(fgets(line, 256, usrdb) != NULL) {
            usrname = strtok(line, ":");
            strtok(NULL, ":");
            usr = atoi(strtok(NULL, ":"));

            if (usr == uid) {
                return TRUE;
            }
        }
        fclose(usrdb);
    }
    return FALSE;
}


int main(argc,argv)
int argc;
char**  argv;
{
    int i = 0;
    int valor = 32;
    int r;

    char* fname;
    char* permisos_bin;

    FILE* usrdb;
    char* usrname;
    char line[256];
    short usr = 0;
    short permisos = 0;
    short lista[ITEMS_ACL];

    if (argc < 4) {
        printf("Error: falta un argumento!\n");
        usage();
        return MISSING_ARG;
    }

    if (strlen(argv[1]) > PATH_MAX) {
        printf("Error: la ruta al archivo es demasiado larga!\n");
        return BAD_PATH;
    }
    
    fname = argv[1];
    
    /* Leo el nombre de usuario o UID de la consola */
    usrdb = fopen(PASSWD_FILE, "r");
    if (usrdb != NULL) {
        while(fgets(line, 256, usrdb) != NULL) {
            usrname = strtok(line, ":");
            strtok(NULL, ":");

            if (strcmp(usrname, argv[2]) == 0) {
                usr = atoi(strtok(NULL, ":"));
                break;
            }
        }
        fclose(usrdb);
    }

    if (usr == 0) {
        usr = (short) atoi(argv[2]);
    
        sprintf(line, "%d", usr);
        if (usr == 0 || strcmp(line, argv[2]) != 0) {
            printf("Error: ID de usuario no valido!\n");
            return BAD_USR;
        }
    }

    /* Advierto al usuario si no existe un usuario con ese UID */
    if (!existeUID(usr)) {
        printf("Advertencia: el ID de usuario proporcionado no existe!\n");
    }


    /* Leo los permisos en binario de la linea de comandos (6 bits) */
    permisos_bin = argv[3];
    while (i < 6) {
        if (permisos_bin[i] == '1') {
            permisos+=valor;
        } else {
            if (permisos_bin[i] != '0') {
                printf("Error: permisos no validos!\n");
                printf("Los permisos deben ser un numero binario de 6 digitos.\n");
                return BAD_PERM;
            }
        }
        valor = valor / 2;
        i = i + 1;
    }

    if (permisos_bin[6] != '\0') {
        printf("Error: permisos no validos!\n");
        printf("Los permisos deben ser un numero binario de 6 digitos.\n");
        return BAD_PERM;
    }

    /* Realizo los cambios */
    r = aclsetuid(fname, usr, permisos);
    
    /* Chequeo de errores */
    if (r == FULL_ACL) {
        printf("Error: la ACL del archivo esta llena!\n");
    }
    
    if (r == INODO_SIN_ACL) {
        printf("Error: el archivo no tiene ACL!\n");
        return r;
    }
    
    if (r == ERR_PIPE) {
        printf("Error: los pipes no soportan ACL!\n");
        return r;
    }

    if (r == ERR_PRIV) {
        printf("Error: permiso denegado!\n");
        return r;
    }

    if (r == ERR_INODO) {
        printf("Error: no se pudo acceder al archivo!\n");
        return r;
    }

    if (r == ERR_INODO_RO) {
        printf("Error: el archivo es de solo lectura!\n");
        return r;
    }
    
    if (r == ERR_SYS_COPY) {
        printf("Error: se produjo un error al copiar datos!\n");
        return r;
    }

    if (r != ACL_OK) {
        printf("Error: se produjo un error al intentar modificar el ACL!\n");
        return r;
    }
    
    return r;
}
